//
//  BaseFormViewController.swift
//  suda
//
//  Created by youai on 2019/7/29.
//  Copyright © 2019年 youi. All rights reserved.
//

import Foundation
import UIKit
import RxSwift
import RxCocoa

class BaseFormStruct{
    
    ///所有表单域
    var allField = [BaseFormField]()
    
    private var _scrollViewClosed : Bool = false
    private var scrollViewClosed : Bool  {
        if (allField.last == nil) || (_scrollView == nil) {
            return false
        }
        if !_scrollViewClosed {
            scrollView.bottomEqualTo(allField.last!)
            _scrollViewClosed = true
        }
        return _scrollViewClosed
    }
    ///封闭scrollView(让底部和最后一个表单域的底部平齐）
    func closeScrollView(){
        _ = self.scrollViewClosed
    }
    
    ///检查所有表单，判断是否需要填写的字段都已经填写了
    func checkRequireLimit()->Bool{
        for field in allField {
            if field.requiredInfo == nil || (!field.isEnabled) { continue }
            if field.isEmpty() {
                UIViewController.topMostController()?.showAlert(content: field.requiredInfo!)
                return false
            }
        }
        return true
    }
    
    let bottomButtonTitle:String?
    init(bottomButtonTitle:String? = nil){
        self.bottomButtonTitle = bottomButtonTitle
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    var bottomButton : Button? = nil
    
    var _scrollView : ConstraintsScrollView? = nil
    
    var scrollView : ConstraintsScrollView {
        if _scrollView==nil && formVC != nil {
           _scrollView = formVC?.scrollView
        }
        return _scrollView!
    }
    
    func _drawScrollView(formVC :BaseFormViewController)->ConstraintsScrollView {

        if bottomButtonTitle == nil   {
            return formVC._origin_drawScrollView()
        }
        
        let box = formVC.safeView.drawView { (make) in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(127)
        }
        
        bottomButton = box.drawButton(title: bottomButtonTitle, titleColor: .white, fontSize: 14, fontWeight:.medium) { (make) in
            make.width.equalToSuperview().multipliedBy(284.0/375.0)
            make.centerX.equalToSuperview()
            make.top.equalToSuperview().offset(41)
            make.height.equalTo(38)
        }
        bottomButton!.drawGradientLayer(color1: .x2AB561, color2: .x16BA7E, x1: 0.5, y1: 0, x2: 0.5, y2: 1.0)
        bottomButton!.cornerRadius(38*0.5).clipsToBounds = true
        
        let s = ConstraintsScrollView()
        formVC.safeView.addSubview(s)
        s.snp.makeConstraints({ (make) in
            make.left.right.equalToSuperview()
            make.top.equalTo(formVC.headView.snp.bottom)
            make.bottom.equalTo(bottomButton!.snp.top)
        })
        return s
    }
    
    func drawRawScrollView(container : UIView)->ConstraintsScrollView {
        let s = ConstraintsScrollView()
        container.addSubview(s)
        
        if bottomButtonTitle == nil   {
            s.snp.makeConstraints({ (make) in
                make.left.right.equalToSuperview()
                make.top.bottom.equalToSuperview()
            })
            _scrollView = s
            return s
        }
        
        let box = container.drawView { (make) in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(127)
        }
        
        bottomButton = box.drawButton(title: bottomButtonTitle, titleColor: .white, fontSize: 14, fontWeight:.medium) { (make) in
            make.width.equalToSuperview().multipliedBy(284.0/375.0)
            make.centerX.equalToSuperview()
            make.top.equalToSuperview().offset(41)
            make.height.equalTo(38)
        }
        bottomButton!.drawGradientLayer(color1: .x2AB561, color2: .x16BA7E, x1: 0.5, y1: 0, x2: 0.5, y2: 1.0)
        bottomButton!.cornerRadius(38*0.5).clipsToBounds = true

        
        s.snp.makeConstraints({ (make) in
            make.left.right.equalToSuperview()
            make.top.equalTo(container)
            make.bottom.equalTo(bottomButton!.snp.top)
        })
        _scrollView = s
        return s
    }
    
    func allPropertyToField(){
        allField.forEach{ $0.propertyToField() }
    }
    
    func allFieldToProperty(){
        allField.forEach{ $0.fieldToProperty() }
    }
    
    func allFieldSetEnabled(_ enabled:Bool){
        allField.forEach { $0.isEnabled = enabled }
    }
    
    weak var formVC : BaseFormViewController? = nil
    
    func createAccessoryToolBar()->UIToolbar?{
        if formVC != nil {
            return formVC?.createAccessoryToolBar()
        }
        if let vc = UIViewController.topMostController() as? BaseViewController {
            return vc.createAccessoryToolBar()
        }
        return nil
    }
}

class BaseFormViewController : BaseViewControllerWithHeader {
    let formStrut : BaseFormStruct
    init(bottomButtonTitle:String? = nil){
        formStrut = BaseFormStruct(bottomButtonTitle: bottomButtonTitle)
        super.init()
        formStrut.formVC = self
    }
    
    override func _drawScrollView() -> ConstraintsScrollView {
        return formStrut._drawScrollView(formVC: self)
    }
    fileprivate func _origin_drawScrollView() -> ConstraintsScrollView {
        return super._drawScrollView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    ///封闭scrollView(让底部和最后一个表单域的底部平齐）
    func closeScrollView(){
        formStrut.closeScrollView()
    }
    func allPropertyToField(){
        formStrut.allPropertyToField()
    }
    
    func allFieldToProperty(){
        formStrut.allFieldToProperty()
    }
    
    func allFieldSetEnabled(_ enabled:Bool){
        formStrut.allFieldSetEnabled(enabled)
    }
    func checkRequireLimit()->Bool{
        return formStrut.checkRequireLimit()
    }
    var bottomButton : Button? {
        return formStrut.bottomButton
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        formStrut.closeScrollView()
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        formStrut.closeScrollView()
    }
}


/**
 基本的空白表单域
 */
class BaseFormField : UIView {
    weak var topView : UIView? = nil
    ///只用于重新调整高度
    var topOffset : CGFloat = 1
    /**
     将表单行加入界面
     - Parameter formVC: 表单视图，向该视图内加入该行
     - Parameter height: 该区域高度
     - Parameter topOffset: 离上一个表单域空多少空间，如果是第一个表单域，则忽略该参数
     */
    @discardableResult
    func _addTo(formStruct:BaseFormStruct,height: CGFloat,topOffset: CGFloat)->Self{
        self.backgroundColor = .white
        formStruct.scrollView.contentView.addSubview(self)
        self.snp.makeConstraints { (make) in
            make.left.right.equalToSuperview()
            make.height.equalTo(height)
            if formStruct.allField.count == 0 {
                make.top.equalToSuperview()
                topView = nil
                //如果第一行就需要预留空位，此写法有问题
                self.topOffset = 0
            }else{
                topView = formStruct.allField.last
                make.top.equalTo(topView!.snp.bottom).offset(height<topOffset ? height : topOffset)
                self.topOffset = topOffset
            }
        }
        formStruct.allField.append(self)
        return self
    }
    
    @discardableResult
    func _addTo(formVC:BaseFormViewController,height: CGFloat,topOffset: CGFloat)->Self{
        return _addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset)
    }

    ///将变量访问器上的值赋到表单显示标签或者输入框去
    func propertyToField(){
    }
    
    ///将表单输入的值赋到变量访问器里去
    func fieldToProperty(){
    }
    
    ///判断表单域是否未填入内容
    func isEmpty()->Bool{ return false }
    
    ///设定该表单域对应的字段为必填字段，并设定当未填入内容的时候弹出的提示信息
    var requiredInfo : String? = nil
    
    ///当需要动态修改表单域高度的时候调用
    func resetHeight(height:CGFloat){
        self.snp.remakeConstraints { (make) in
            make.left.right.equalToSuperview()
            make.height.equalTo(height)
            if topView == nil {
                make.top.equalToSuperview()
            }else{
                make.top.equalTo(topView!.snp.bottom).offset(height<topOffset ? height : topOffset)
            }
        }
    }
    
    var isEnabled : Bool = true
}

///有一个title和一个变量访问器的表单域
class FormFieldWithTitle : BaseFormField {
    
    ///左侧标签对象
    let titleLabel = UILabel()
    ///右侧向右的小箭头（如果需要）
    let rightArrow : UIImageView?
    /// 输入框距离右边距，或者右侧小箭头有多远
    var rightOffset : CGFloat? = nil
    
    /**
     表单字段
     - Parameter title: 左侧标题
     - Parameter withRightArrow: 是否在右侧显示一个小箭头（一般代表打开选择界面）
     */
    init(title:String,withRightArrow:Bool = false){
        if withRightArrow {
            rightArrow = UIImageView(image: UIImage(named: "right_arrow_gray"))
        }else{
            rightArrow = nil
        }
        super.init(frame: .zero)
        titleLabel.text = title
    }

    /**
     将表单行加入界面
     - Parameter formVC: 表单视图，向该视图内加入该行
     - Parameter rightOffset: 输入框距离右边距，或者右侧小箭头有多远，不输入会使用默认值
     */
    @discardableResult
    func addTo(formVC:BaseFormViewController,height:CGFloat=44,topOffset:CGFloat=1,rightOffset: CGFloat? = nil)->Self{
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    
    @discardableResult
    func addTo(formStruct:BaseFormStruct,height:CGFloat=44,topOffset:CGFloat=1,rightOffset: CGFloat? = nil)->Self{
        self.rightOffset = rightOffset
        super._addTo(formStruct: formStruct, height: height, topOffset: topOffset)
        self.drawLabel(label: titleLabel, text: titleLabel.text ?? "", fontSize: 14, textColor: .x333333) { (make) in
            make.centerY.equalToSuperview()
            make.left.equalToSuperview().offset(17)
        }
        if rightArrow != nil {
            self.addSubview(rightArrow!)
            rightArrow!.snp.makeConstraints { (make) in
                make.right.equalToSuperview().offset(-19)
                make.centerY.equalToSuperview()
            }
        }
        return self
    }
    
    ///关联的变量访问器（可以从访问器加载变量，也可以把表单输入的值赋到访问器里去）
    var propertyAccessor : PropertyAccessor? = nil
    
    ///将当前表单行绑定到一个变量访问器上
    @discardableResult
    func bindTo(_ propertyAccessor:PropertyAccessor)->Self{
        self.propertyAccessor = propertyAccessor
        propertyToField()
        return self
    }
    
//    fileprivate var _twoDecimalPlaces = false
//    func hasTwoDecimalPlaces()->Self{
//        _twoDecimalPlaces = true
//        return self
//    }
    
    func propertyToString() -> String? {
        if let v =  propertyAccessor?.getter() {
            if let s = v as? String {
                return s
            }else if let d = v as? Double {
//                if _twoDecimalPlaces {
//                    return String(format:"%.2f",d)
//                }else{
                    return d.clean
//                }
            }else{
                return String(describing: v)
            }
        }
        return nil
    }
    
    ///根据变量访问器的值判断当前是否为空
    override func isEmpty()->Bool{
        if propertyAccessor == nil {
            return false
        }
        if let result = propertyAccessor?.getter() {
            if let str = result as? String {
                return str.count == 0
            }
            return false
        }else{
            return true
        }
    }
    
    override var isEnabled : Bool { didSet{
        if isEnabled {
            titleLabel.textColor = .x333333
        }else{
            titleLabel.textColor = .x999999
        }
        }}
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

///仅有一个显示标签（不可输入）的表单行
class BaseFormLabel : FormFieldWithTitle {
    let contentLabel = UILabel()
    
    @discardableResult
    override func addTo(formVC: BaseFormViewController,height:CGFloat=44,topOffset:CGFloat=1,rightOffset:CGFloat? = nil)->Self {
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    @discardableResult
    override func addTo(formStruct: BaseFormStruct,height:CGFloat=44,topOffset:CGFloat=1,rightOffset:CGFloat? = nil)->Self {
        _ = super.addTo(formStruct: formStruct,height: height,topOffset: topOffset, rightOffset: rightOffset)
        drawLabel(label: contentLabel, text: contentLabel.text ?? "", fontSize: 14,  textColor: .x666666) { (make) in
            if rightArrow != nil {
                make.right.equalTo(rightArrow!.snp.left).offset(rightOffset ?? -16)
            }else{
                make.right.equalToSuperview().offset(rightOffset ?? -22)
            }
            make.left.greaterThanOrEqualTo(titleLabel.snp.right).offset(5)
            make.centerY.equalToSuperview()
        }
        contentLabel.horizontalFittingSize()
        return self
    }
    
    override func propertyToField() {
        if propertyAccessor != nil {
            let content = propertyToString()
            contentLabel.text = content
        }
    }
    
}

///有单行输入框的表单行
class FormTextField : FormFieldWithTitle,UITextFieldDelegate {
    
    let textField = TextField()
    
    var _didEndEditingSubject : PublishSubject<()>? = nil
    ///结束编辑时触发
    lazy var didEndEditingSubject : PublishSubject<()> = {
        if _didEndEditingSubject == nil {
            _didEndEditingSubject = PublishSubject<()>()
            _ = _didEndEditingSubject?.takeUntil(self.rx.deallocated)
        }
        return _didEndEditingSubject!
    }()
    
    /**
     有单行输入框的表单行
     - Parameter title: 左侧标题
     - Parameter withRightArrow: 是否在右侧显示一个小箭头（一般代表打开选择界面）
     - Parameter placeholder: 占位提示字符串
     - Parameter keyboardType: 选择特殊的输入键盘
     */
    init(title: String, withRightArrow:Bool = false,placeholder:String,keyboardType : UIKeyboardType = .default) {
        super.init(title: title,withRightArrow: withRightArrow)
        textField.placeholder = placeholder
        textField.keyboardType = keyboardType
    }
    @discardableResult
    override func addTo(formVC: BaseFormViewController,height:CGFloat=44,topOffset:CGFloat=1,rightOffset:CGFloat? = nil)->Self {
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    @discardableResult
    override func addTo(formStruct: BaseFormStruct,height:CGFloat=44,topOffset:CGFloat=1,rightOffset:CGFloat? = nil)->Self {
        _ = super.addTo(formStruct: formStruct,height: height,topOffset: topOffset,rightOffset: rightOffset)
        self.drawTextField(textField: textField, placeholder: textField.placeholder,
                           fontSize: 14, keyboardType: textField.keyboardType, returnKeyType: .done) { (make) in
                            if rightArrow != nil {
                                make.right.equalTo(rightArrow!.snp.left).offset(rightOffset ?? -16)
                            }else{
                                make.right.equalToSuperview().offset(rightOffset ?? -22)
                            }
                            make.centerY.equalToSuperview()
                            make.left.equalTo(titleLabel.snp.right).offset(20)
//                            make.left.greaterThanOrEqualTo(titleLabel.snp.right).offset(20)
//                            make.width.greaterThanOrEqualToSuperview().multipliedBy(0.5).priority(.low)
        }
        textField.horizontalFittingSize()
        textField.hitEdgInsets = .init(top: -20, left: -20, bottom: -20, right: -20)
        textField.textAlignment = .right
        textField.textColor = .x666666
        textField.clearButtonMode = .whileEditing
        
        textField.inputAccessoryView =  formStruct.createAccessoryToolBar()
        
        textField.delegate = self
        
        return self
    }
    
    override func propertyToField() {
        textField.text = propertyToString()
    }
    
    override func fieldToProperty() {
        propertyAccessor?.setter(textField.text)
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool{
        return true
    }
    
    func textFieldDidEndEditing(_ textField: UITextField){
//        if _twoDecimalPlaces {
//            fieldToProperty()
//            propertyToField()
//        }
        _didEndEditingSubject?.onNext(())
    }
    
    override var isEnabled: Bool { didSet{
        textField.isEnabled = isEnabled
        }}
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}


///日期选择框
class FormDateSelector : FormTextField {
    let datePicker = DatePickerForTextField()
    var dateType = UIDatePicker.Mode.date
    
    func setDateType(_ dt:UIDatePicker.Mode) -> Self {
        dateType = dt
        return self
    }
    @discardableResult
    override func addTo(formVC: BaseFormViewController,height:CGFloat=44,topOffset:CGFloat=1,rightOffset:CGFloat? = nil) -> Self {
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    @discardableResult
    override func addTo(formStruct: BaseFormStruct,height:CGFloat=44,topOffset:CGFloat=1,rightOffset:CGFloat? = nil) -> Self {
        _ = super.addTo(formStruct: formStruct,height: height,topOffset: topOffset,rightOffset: rightOffset)
        datePicker.setTextField(textField, type: dateType)
        textField.inputAccessoryView = formStruct.createAccessoryToolBar()
        return self
    }
    
    override func propertyToField() {
        super.propertyToField()
        if let dateStr = textField.text, dateStr.lengthOfBytes(using: .utf8) > 0 {
            if let date = datePicker.dateFormatter.date(from: dateStr) {
                datePicker.date = date
            }else{
                datePicker.date = Date()
            }
        }else{
            datePicker.date = Date()
        }
    }
}

//复选框协议
@objc protocol FormMultipleSelectFieldDelegate {
    func formMultipleLeftBtnClcik(selIndex:[Int], titleAry:[String])
}
//复选框表单
class FormMultipleSelectField : BaseFormField {
    
    weak var selecteDelegate: FormMultipleSelectFieldDelegate?
    var selectindexs:[Int]=[]//选中的
    var buttons:[Button]=[]//按钮索引
    
    //标题数组
    var titleArr:[String]=[""]{
        didSet{
            for i in  0..<titleArr.count{
                //组装按钮和label
                let singleselectview:UIView=UIView.init(frame: CGRect.init(x: i*100, y: 0, width: 100, height: 50))
                let rightLbel = UILabel()
                let leftBtn = Button()
                
                //                let leftBtn:UIButton=UIButton.init(frame: CGRect.init(x: 10, y: 10, width: 30, height: 30))
                                leftBtn.tag=130+i;
                //                leftBtn.setImage(UIImage.init(named: "xuanzekuang_normal"), for: UIControl.State.normal)
                //                leftBtn.addTarget(self, action: #selector(leftBtnClcik), for: UIControl.Event.touchUpInside)
                //                singleselectview.addSubview(leftBtn)
                
                singleselectview.drawButton(button:leftBtn, title: "", titleColor: .white, fontSize: 14, fontWeight:.medium) { (make) in
                    make.left.equalToSuperview().offset(10)
                    make.top.equalToSuperview().offset(10)
                    make.width.equalTo(30)
                    make.height.equalTo(30)
                }
                leftBtn.hitEdgInsets = .init(top: -100, left: -100, bottom: -100, right: -100)
                leftBtn.addTarget(self, action: #selector(leftBtnClcik), for: UIControl.Event.touchUpInside)
                leftBtn.setImage(UIImage.init(named: "xuanzekuang_normal"), for: UIControl.State.normal)
                leftBtn.setImage(UIImage.init(named: "xuanzekuang_sel"), for: UIControl.State.selected)
                buttons.append(leftBtn)
                
                singleselectview.drawLabel(label: rightLbel, text: titleArr[i], fontSize: 14, textColor: .x333333) { (make) in
                    make.centerY.equalTo(leftBtn.snp.centerY)
                    make.left.equalTo(leftBtn.snp.right).offset(9)
                }
                
                addSubview(singleselectview)
            }
        }
    }
    
    //单独加载
    //    override init(frame: CGRect) {
    //        super.init(frame: frame)
    //        initViews()
    //    }
    //
    //    required init?(coder aDecoder: NSCoder) {
    //        fatalError("init(coder:) has not been implemented")
    //    }
    //
    //    func initViews(){
    //        let sureBtn:UIButton=UIButton.init(frame: CGRect.init(x: 200, y: 10, width: 100, height: 50))
    //        sureBtn.setTitle("确认", for: UIControl.State.normal)
    //        sureBtn.setTitleColor(UIColor.black, for: UIControl.State.normal)
    //        sureBtn.addTarget(self, action: #selector(sureBtnClcik), for: UIControl.Event.touchUpInside)
    //        addSubview(sureBtn)
    //    }
    /////////
    
    //表单加载
    func addTo(formVC: BaseFormViewController,topOffset:CGFloat = 0,selAry:Array<String> = []){
        addTo(formStruct: formVC.formStrut, topOffset: topOffset, selAry: selAry)
    }
    func addTo(formStruct: BaseFormStruct,topOffset:CGFloat = 0,selAry:Array<String> = []){
        _addTo(formStruct: formStruct, height: 44, topOffset: topOffset)
        titleArr = selAry
    }
    ///////
    
    //事件监听
    //确认按钮,根据选中的按钮索引做相应的操作
    @objc func sureBtnClcik(){
        print("\(selectindexs)")
    }
    
    //点击按钮选中或取消
    @objc func leftBtnClcik(sender:UIButton){
        sender.isSelected = !sender.isSelected
        let btnTag:Int=sender.tag
        if sender.isSelected{//选中
            selectindexs.append(btnTag)//吧按钮的索引存储起来
        }else {
            //删除数组中的元素，采用过滤的方法，swift中没有现成f的方法
            let fiflter:[Int]=selectindexs.filter {
                $0 != btnTag
            }
            selectindexs = fiflter
        }
        
        //调用代理方法
        if selecteDelegate != nil
        {
            selecteDelegate?.formMultipleLeftBtnClcik(selIndex:selectindexs, titleAry: titleArr)
            //            self.navigationController?.popToRootViewControllerAnimated(true)
        }
    }
    /////////
}


//表单提交按钮
class FormButtonField : BaseFormField {
    
    let button = Button()
    let buttonTitle:String
    init(buttonTitle:String){
        self.buttonTitle = buttonTitle
        super.init(frame: .zero)
    }
    func addTo(formVC: BaseFormViewController,height:CGFloat=102, buttonTopOffset:CGFloat=25){
        addTo(formStruct: formVC.formStrut, height: height, buttonTopOffset: buttonTopOffset)
    }
    func addTo(formStruct: BaseFormStruct,height:CGFloat=102, buttonTopOffset:CGFloat=25){
        super._addTo(formStruct: formStruct, height: height, topOffset: 0)
        self.backgroundColor = .clear
        drawButton(button:button, title: buttonTitle, titleColor: .white, fontSize: 14, fontWeight:.medium) { (make) in
            make.width.equalToSuperview().multipliedBy(284.0/375.0)
            make.centerX.equalToSuperview()
            make.top.equalToSuperview().offset(buttonTopOffset)
            make.height.equalTo(38)
        }
        button.setTitleColor(.x999999, for: .disabled)
        button.drawGradientLayer(color1: .x2AB561, color2: .x16BA7E, x1: 0.5, y1: 0, x2: 0.5, y2: 1.0)
        button.cornerRadius(38*0.5).clipsToBounds = true
    }
    override var isEnabled : Bool { didSet{
        self.button.isEnabled = self.isEnabled
        }}
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

//多行文本框
class FormTextViewField : FormFieldWithTitle,UITextViewDelegate {
    
    let textView = UITextView()
    let placeholderLabel = UILabel()
    
    init(title: String,placeholder:String?,  withRightArrow: Bool = false) {
        super.init(title: title, withRightArrow: withRightArrow)
        placeholderLabel.text = placeholder
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @discardableResult
    override func addTo(formVC: BaseFormViewController, height: CGFloat = 44+117, topOffset: CGFloat = 1, rightOffset: CGFloat? = nil) -> Self {
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    @discardableResult
    override func addTo(formStruct: BaseFormStruct, height: CGFloat = 44+117, topOffset: CGFloat = 1, rightOffset: CGFloat? = nil) -> Self {
        self.rightOffset = rightOffset
        super._addTo(formStruct: formStruct, height: height, topOffset: topOffset)
        self.backgroundColor = .clear
        self.drawLabel(label: titleLabel, text: titleLabel.text ?? "", fontSize: 14, textColor: .x333333) { (make) in
            make.centerY.equalTo(self.snp.top).offset(13+20*0.5)
            make.left.equalToSuperview().offset(17)
        }
        if rightArrow != nil {
            self.addSubview(rightArrow!)
            rightArrow!.snp.makeConstraints { (make) in
                make.right.equalToSuperview().offset(-19)
                make.centerY.equalTo(titleLabel)
            }
        }
        
        let box = self.drawView { make in
            make.left.right.equalToSuperview()
            make.top.equalTo(self.snp.top).offset(44)
            make.bottom.equalToSuperview()
        }
        box.backgroundColor = .white
        box.addSubview(textView)
        textView.snp.makeConstraints { (make) in
            make.left.equalToSuperview().offset(11)
            make.top.equalToSuperview().offset(5)
            make.right.equalToSuperview().offset(-11)
            make.bottom.equalToSuperview().offset(-5)
        }
        textView.font = UIFont.systemFont(ofSize: 13)
        textView.backgroundColor = .clear
        textView.delegate = self
        
        box.drawLabel(label: placeholderLabel, text: placeholderLabel.text ?? "请输入\(titleLabel.text ?? "")内容", fontSize: 13, textColor: .x999999) { (make) in
            make.left.equalToSuperview().offset(17)
            make.top.equalToSuperview().offset(13)
        }
        return self
    }
    
    override func propertyToField() {
        textView.text = propertyToString()
        textViewDidChange(textView)
    }
    
    override func fieldToProperty() {
        propertyAccessor?.setter(textView.text)
    }
    
    func textViewDidChange(_ textView: UITextView){
        let text:String = textView.text
        placeholderLabel.isHidden = text.count > 0
    }
    override var isEnabled : Bool { didSet{
        self.textView.isEditable = self.isEnabled
        }}
}


enum EnumFormSwitchType {
    case BOOL
    case TorF
    case OneOrZero
}

///用switch外观的单选样式
class FormSwitchField : FormFieldWithTitle{
    
    let type : EnumFormSwitchType
    let switchView = UISwitch()
    
    init(title: String, withRightArrow: Bool = false, type : EnumFormSwitchType = .TorF) {
        self.type = type
        super.init(title: title, withRightArrow: withRightArrow)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    @discardableResult
    override func addTo(formVC: BaseFormViewController, height: CGFloat = 44, topOffset: CGFloat = 1, rightOffset: CGFloat? = nil) -> Self {
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    
    @discardableResult
    override func addTo(formStruct: BaseFormStruct, height: CGFloat = 44, topOffset: CGFloat = 1, rightOffset: CGFloat? = nil) -> Self {
        super.addTo(formStruct: formStruct, height: height, topOffset: topOffset, rightOffset: rightOffset)
        addSubview(switchView)
        switchView.snp.makeConstraints { (make) in
            make.centerY.equalToSuperview()
            make.right.equalToSuperview().offset(rightOffset ?? -33)
            make.width.equalTo(35)
//            make.height.equalTo(21)
        }
        return self
    }
    
    override func propertyToField() {
        if let value = propertyAccessor?.getter() {
            switch(type){
            case .BOOL:
                switchView.isOn = (value as? Bool) ?? false
            case .TorF:
                switchView.isOn = ((value as? String)?.starts(with: "T")) ?? false
            case .OneOrZero:
                switchView.isOn = (value as? Int) == 1
            }
        }else{
            switchView.isOn = false
        }
    }
    
    override func fieldToProperty() {
        switch(type){
        case .BOOL:
            propertyAccessor?.setter(switchView.isOn)
        case .TorF:
            propertyAccessor?.setter(switchView.isOn ? "T" : "F")
        case .OneOrZero:
            propertyAccessor?.setter(switchView.isOn ? 1 : 0)
        }
    }
    
    override var isEnabled : Bool { didSet{
        self.switchView.isEnabled = self.isEnabled
        }}
}

///用左侧checkbox外观的单选样式
///暂时用字母T和F表示是否选中，不支持自定义
class FormCheckboxField : BaseFormField {
    
    let checkButton = Button()

    init(title:String){
        super.init(frame: .zero)
        checkButton.setTitle("  "+title, for: .normal)
    }
    
    ///关联的变量访问器（可以从访问器加载变量，也可以把表单输入的值赋到访问器里去）
    var propertyAccessor : PropertyAccessor? = nil
    
    ///将当前表单行绑定到一个变量访问器上
    @discardableResult
    func bindTo(_ propertyAccessor:PropertyAccessor)->Self{
        self.propertyAccessor = propertyAccessor
        propertyToField()
        return self
    }
    @discardableResult
    func addTo(formVC: BaseFormViewController, height: CGFloat = 44, topOffset: CGFloat = 1, rightOffset: CGFloat? = nil) -> Self {
        return addTo(formStruct: formVC.formStrut, height: height, topOffset: topOffset, rightOffset: rightOffset)
    }
    @discardableResult
    func addTo(formStruct: BaseFormStruct, height: CGFloat = 44, topOffset: CGFloat = 1, rightOffset: CGFloat? = nil) -> Self {
        super._addTo(formStruct: formStruct, height: height, topOffset: topOffset)
        drawButton(button: checkButton, title: checkButton.title(for: .normal), titleColor: .x333333, fontSize: 14) { (make) in
            make.left.equalToSuperview().offset(20)
            make.centerY.equalToSuperview()
        }
        checkButton.setImage(UIImage(named: "login_notchecked"), for: .normal)
        checkButton.setImage(UIImage(named: "login_checked"), for: .selected)
        checkButton.hitEdgInsets = .init(top: -20, left: -20, bottom: -20, right: -400)
        checkButton.addTarget(self, action: #selector(onCheckButtonClicked(button:)), for: .touchUpInside)
        return self
    }
    
    @objc func onCheckButtonClicked(button:Button?){
        if !self.isEnabled {
            return
        }
        if checkButton.isSelected {
            checkButton.isSelected = false
            propertyAccessor?.setter("F")
        }else{
            checkButton.isSelected = true
            propertyAccessor?.setter("T")
        }
    }
    
    override func propertyToField() {
        checkButton.isSelected = propertyAccessor?.getter() as? String == "T"
    }
    
    override func fieldToProperty() {
        propertyAccessor?.setter( checkButton.isSelected ? "T" : "F" )
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}


///包含日期起止区间的过滤区
class FormDateFilterArea : BaseFormField {
    let titleLabel = UILabel()
    init(title:String? = "时间区间"){
        super.init(frame: .zero)
        titleLabel.text = title
    }
    
    let beginDateTextField = TextField()
    let endDateTextField = TextField()
    let beginDatePicker = DatePickerForTextField()
    let endDatePicker = DatePickerForTextField()
    func addTo(formVC: BaseFormViewController,topOffset:CGFloat = 0){
        addTo(formStruct: formVC.formStrut, topOffset: topOffset)
    }
    func addTo(formStruct: BaseFormStruct,topOffset:CGFloat = 0){
        if titleLabel.text?.nilIfEmpty != nil {
            self.drawLabel(label: titleLabel, text: titleLabel.text, fontSize: 14, textColor: .x333333) { (make) in
                make.centerY.equalTo(self.snp.top).offset(9+20*0.5)
                make.left.equalToSuperview().offset(17)
            }
            _addTo(formStruct: formStruct, height: 40+44, topOffset: topOffset)
        }else{
            _addTo(formStruct: formStruct, height: 44, topOffset: topOffset)
        }
        self.backgroundColor = .clear
        let box = drawView { (make) in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(44)
        }
        box.backgroundColor = .white
        
        func drawDateField(leftOffset:CGFloat,textField:TextField,datePicker:DatePickerForTextField) {
            let tfBackground = box.drawView { (make) in
                make.left.equalToSuperview().offset(leftOffset)
                make.centerY.equalToSuperview()
                make.width.equalTo(130)
                make.height.equalTo(25)
            }
            tfBackground.backgroundColor = .xF0F0F0
            tfBackground.cornerRadius(13)
            let img = tfBackground.drawImage(named: "form_calendar") { (make) in
                make.right.equalToSuperview().offset(-14)
                make.centerY.equalToSuperview()
            }
            let textField = tfBackground.drawTextField(textField:textField, placeholder: "", fontSize: 13) { (make) in
                make.centerY.equalToSuperview()
                make.left.equalToSuperview().offset(10)
                make.right.equalTo(img.snp.left).offset(+15)
            }
            textField.hitEdgInsets = .init(top: -10, left: -10, bottom: -10, right: -10)
            datePicker.setTextField(textField)
            textField.inputAccessoryView = formStruct.createAccessoryToolBar()
            if textField.clearButtonMode != .never {
                textField.clearButtonMode = .whileEditing
            }
        }
        
        ///当前日期
        let today = Date()
        //默认起始日期为当前日期向前一个月
        let beginDate = today.aMonthAgo
        
        drawDateField(leftOffset: 20,textField: beginDateTextField,datePicker: beginDatePicker)
        beginDatePicker.date = beginDate
        
        box.drawLabel(text: "至", fontSize: 14, textColor: .x666666) { (make) in
            make.centerX.centerY.equalToSuperview()
        }
        
        drawDateField(leftOffset: 224,textField: endDateTextField,datePicker: endDatePicker)
        endDatePicker.date = today
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    var beginDateStr : String? {
        return beginDateTextField.textOrNil()
    }
    var endDateStr : String? {
        return endDateTextField.textOrNil()
    }
    var beginToEndDateStr : String? {
        let begin = beginDateStr
        let end = endDateStr
        if begin == nil && end == nil {
            return nil
        }
        let beginDateStr2 = begin?.replacingOccurrences(of: "-", with: ".") ?? ""
        let endDateStr2 = end?.replacingOccurrences(of: "-", with: ".") ?? ""
        return "\(beginDateStr2)-\(endDateStr2)"
    }
    //暂时不需要实现isEnabled
}

